import javax.swing.*;
import java.awt.*;

public class ElevatorGUI {
    private Elevator elevator;
    private JLabel floorLabel;
    private JLabel stateLabel;
    private JLabel waitTimeLabel;
    private JLabel directionLabel; // 显示方向 ↑ 或 ↓
    private JLabel peopleCountLabel; // 显示电梯人数
    private JTextField inputField; // 输入目标楼层
    private JTextField enterCountField; // 输入进入人数
    private JTextField exitCountField; // 输入出去人数
    private JTextArea logArea; // 用于显示电梯操作日志
    private Timer waitTimer;
    private Timer doorTimer; // 用于 50t 自动关门的定时器
    private int waitTime = 300; // 300t 等待时间
    private boolean hasReturnedToBase = false; // 标志位，防止重复弹出对话框
    private JPanel elevatorPanel; // 电梯绘图面板
    private int elevatorYPosition; // 电梯的 Y 坐标
    private boolean doorOpen; // 记录电梯门的状态
    private int leftDoorX, rightDoorX; // 左右门的 X 坐标，用于动态开关门

    public ElevatorGUI() {
        elevator = new Elevator(this); // 传递 GUI 引用给电梯对象
        doorOpen = false; // 初始状态为门关闭
        leftDoorX = 20;  // 左侧门初始位置
        rightDoorX = 50; // 右侧门初始位置
        createAndShowGUI();
    }

    private void createAndShowGUI() {
        JFrame frame = new JFrame("电梯模拟系统");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 设置固定窗口大小
        frame.setSize(800, 700);
        frame.setLocationRelativeTo(null); // 窗口居中显示

        // 设置字体
        Font font = new Font("微软雅黑", Font.PLAIN, 28); // 使用微软雅黑，28号字体
        UIManager.put("Label.font", font);
        UIManager.put("TextField.font", font);
        UIManager.put("Button.font", font);
        UIManager.put("TextArea.font", font);

        frame.setLayout(new BorderLayout()); // 使用 BorderLayout 管理布局

        // 顶部状态标签面板
        JPanel statusPanel = new JPanel();
        statusPanel.setLayout(new GridLayout(1, 5)); // 分五部分显示状态

        floorLabel = new JLabel("当前楼层: " + elevator.getCurrentFloor());
        stateLabel = new JLabel("电梯状态: " + elevator.getCurrentState()); // 初始化状态标签
        waitTimeLabel = new JLabel("等待时间: " + waitTime + "t");
        directionLabel = new JLabel("电梯方向: ");
        peopleCountLabel = new JLabel("电梯人数: 0/12"); // 初始化电梯人数标签

        statusPanel.add(floorLabel);
        statusPanel.add(stateLabel);
        statusPanel.add(waitTimeLabel);
        statusPanel.add(directionLabel);
        statusPanel.add(peopleCountLabel); // 添加人数显示

        // 日志区域
        logArea = new JTextArea(); // 用于显示电梯操作日志
        logArea.setEditable(false); // 设置日志区域不可编辑
        JScrollPane logScrollPane = new JScrollPane(logArea);
        logScrollPane.setPreferredSize(new Dimension(800, 150)); // 设置滚动面板大小

        // 电梯面板
        elevatorPanel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                drawElevator(g); // 绘制电梯
                drawFloors(g); // 绘制楼层信息
            }
        };
        elevatorPanel.setPreferredSize(new Dimension(100, 400)); // 设置电梯面板大小

        // 楼层输入和请求按钮
        JPanel controlPanel = new JPanel();
        inputField = new JTextField(5);
        JButton requestButton = new JButton("请求楼层");

        requestButton.addActionListener(e -> {
            int targetFloor;
            try {
                targetFloor = Integer.parseInt(inputField.getText());
                if (targetFloor >= 0 && targetFloor < 8) {
                    hasReturnedToBase = false; // 重置标志位
                    elevator.addRequest(new Request(targetFloor));
                    stopWaitTimer(); // 暂停等待时间计时
                    new ElevatorWorker().execute(); // 启动后台线程处理
                } else {
                    JOptionPane.showMessageDialog(frame, "请输入有效楼层 (0-7)！");
                }
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(frame, "请输入一个数字！");
            }
            inputField.setText("");
        });

        controlPanel.add(new JLabel("目标楼层:"));
        controlPanel.add(inputField);
        controlPanel.add(requestButton);

        // 增加“开门”和“关门”按钮
        JButton openDoorButton = new JButton("开门");
        JButton closeDoorButton = new JButton("关门");

        // 开门按钮点击事件
        openDoorButton.addActionListener(e -> {
            if (!doorOpen) { // 如果门是关闭状态，执行开门动画
                openDoorAnimation();
            }
        });

        // 关门按钮点击事件
        closeDoorButton.addActionListener(e -> {
            if (doorOpen) { // 如果门是打开状态，执行关门动画
                closeDoorAnimation();
            }
        });

        controlPanel.add(openDoorButton);
        controlPanel.add(closeDoorButton);

        // 人员进出输入框
        enterCountField = new JTextField(5);
        exitCountField = new JTextField(5);
        JButton enterButton = new JButton("进入人数");
        JButton exitButton = new JButton("出去人数");

        enterButton.addActionListener(e -> {
            try {
                int count = Integer.parseInt(enterCountField.getText());
                if (count > 0) {
                    elevator.handlePeopleInOut(count, 0); // 进入人数
                    resetDoorTimer(); // 重置关门时间
                } else {
                    JOptionPane.showMessageDialog(frame, "请输入有效的进入人数！");
                }
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(frame, "请输入一个数字！");
            }
            enterCountField.setText(""); // 清空输入框
        });

        exitButton.addActionListener(e -> {
            try {
                int count = Integer.parseInt(exitCountField.getText());
                if (count > 0) {
                    elevator.handlePeopleInOut(0, count); // 出去人数
                    resetDoorTimer(); // 重置关门时间
                } else {
                    JOptionPane.showMessageDialog(frame, "请输入有效的出去人数！");
                }
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(frame, "请输入一个数字！");
            }
            exitCountField.setText(""); // 清空输入框
        });

        controlPanel.add(new JLabel("进入人数:"));
        controlPanel.add(enterCountField);
        controlPanel.add(enterButton);
        controlPanel.add(new JLabel("出去人数:"));
        controlPanel.add(exitCountField);
        controlPanel.add(exitButton);

        // 布局管理
        frame.add(statusPanel, BorderLayout.NORTH);
        frame.add(logScrollPane, BorderLayout.SOUTH);
        frame.add(elevatorPanel, BorderLayout.CENTER);
        frame.add(controlPanel, BorderLayout.EAST);

        frame.setVisible(true);
    }

    // 更新电梯位置并重绘电梯面板
    public void updateElevatorPosition(int currentFloor) {
        elevatorYPosition = 400 - (currentFloor * 50); // 根据楼层动态调整 Y 坐标
        elevatorPanel.repaint(); // 重新绘制电梯
    }

    // 更新电梯状态标签
    public void updateStateLabel(String newState) {
        SwingUtilities.invokeLater(() -> stateLabel.setText(newState));
    }

    // 更新电梯方向标签
    public void updateDirection(String direction) {
        SwingUtilities.invokeLater(() -> directionLabel.setText("电梯方向: " + direction));
    }

    // 更新电梯人数标签
    public void updatePeopleCountLabel() {
        SwingUtilities.invokeLater(() -> peopleCountLabel.setText("电梯人数: " + elevator.getPeopleCount() + "/12"));
    }

    // 停止等待计时器
    private void stopWaitTimer() {
        if (waitTimer != null) {
            waitTimer.stop(); // 停止计时器
        }
    }

    // 启动或重置等待计时器
    private void startWaitTimer() {
        waitTime = 300; // 重置等待时间
        waitTimer = new Timer(100, e -> {
            if (waitTime > 0) {

                waitTimeLabel.setText("等待时间: " + waitTime + "t");
                waitTime--;
            } else if (!hasReturnedToBase) { // 检查标志位，确保只返回一次
                hasReturnedToBase = true; // 设置标志位，防止重复执行
                waitTimer.stop(); // 停止计时器
                showAutoClosingDialog("等待时间超过300t，电梯返回1层！", 2000); // 显示2秒后关闭并逐步返回1层
            }
        });
        waitTimer.start(); // 启动计时器
    }

    // 启动或重置门关定时器 (50t 自动关门)
    private void startDoorTimer() {
        doorTimer = new Timer(5000, e -> {
            closeDoorAnimation(); // 触发关门动画
        });
        doorTimer.setRepeats(false); // 只运行一次
        doorTimer.start(); // 启动计时器
    }

    // 重置门关定时器 (如果有人进出时)
    private void resetDoorTimer() {
        if (doorTimer != null) {
            doorTimer.stop(); // 停止当前计时器
        }
        startDoorTimer(); // 重新启动
    }

    // 启动开门动画
    private void openDoorAnimation() {
        Timer timer = new Timer(50, e -> {
            if (leftDoorX > 0 && rightDoorX < 70) { // 两侧门分别向外移动
                leftDoorX -= 2; // 左门向左移
                rightDoorX += 2; // 右门向右移
                doorOpen = true; // 标记门为打开状态
                elevatorPanel.repaint(); // 重绘电梯
            } else {
                ((Timer) e.getSource()).stop(); // 停止定时器
                startDoorTimer(); // 启动50t内无人则关门
            }
        });
        timer.start();
    }

    // 启动关门动画
    private void closeDoorAnimation() {
        Timer timer = new Timer(50, e -> {
            if (leftDoorX < 20 && rightDoorX > 50) { // 两侧门分别向中间移动
                leftDoorX += 2; // 左门向右移
                rightDoorX -= 2; // 右门向左移
                doorOpen = false; // 标记门为关闭状态
                elevatorPanel.repaint(); // 重绘电梯
            } else {
                ((Timer) e.getSource()).stop(); // 停止定时器
            }
        });
        timer.start();
    }

    // 显示等待超时提示并逐步返回1楼
    private void showAutoClosingDialog(String message, int duration) {
        JDialog dialog = new JOptionPane(message, JOptionPane.INFORMATION_MESSAGE).createDialog("提示");
        Timer timer = new Timer(duration, e -> {
            dialog.setVisible(false);
            dialog.dispose();
            elevator.returnToBase(); // 超时后逐步返回1楼
        });
        timer.setRepeats(false); // 确保定时器只运行一次
        timer.start();
        dialog.setVisible(true); // 显示对话框
    }

    // 更新电梯的状态
    public void updateElevatorStatus(String status) {
        floorLabel.setText("当前楼层: " + status); // 始终更新显示当前楼层
    }

    // 更新电梯的运行日志
    public void updateLog(String logMessage) {
        logArea.append(logMessage + "\n"); // 将日志消息追加到日志区域
    }

    // 绘制电梯
    private void drawElevator(Graphics g) {
        g.setColor(Color.YELLOW); // 设置电梯颜色为黄色
        g.fillRect(20, elevatorYPosition, 60, 30); // 绘制电梯的矩形
        g.setColor(Color.BLACK); // 设置文本颜色为黑色
        g.drawString("电梯", 30, elevatorYPosition + 20); // 在电梯中间绘制标签

        // 绘制门
        g.setColor(Color.GRAY);
        if (doorOpen) {
            // 开门时，左右两侧门逐渐向外打开
            g.fillRect(leftDoorX, elevatorYPosition, 10, 30); // 左侧门
            g.fillRect(rightDoorX, elevatorYPosition, 10, 30); // 右侧门
        } else {
            // 关门时，门完全关闭
            g.fillRect(leftDoorX, elevatorYPosition, 30, 30); // 左侧门
            g.fillRect(rightDoorX, elevatorYPosition, 30, 30); // 右侧门
        }
    }

    // 绘制楼层信息，确保 0-7 层按正确顺序显示
    private void drawFloors(Graphics g) {
        g.setColor(Color.GRAY); // 设置楼层颜色
        for (int i = 0; i < 8; i++) {
            int y = 400 - (i * 50); // 确保 0 楼在最底部，7 楼在顶部
            g.drawString("楼层 " + i, 100, y + 20); // 绘制楼层标签
        }
    }

    // SwingWorker 实现电梯运行的后台任务
    class ElevatorWorker extends SwingWorker<Void, Void> {
        @Override
        protected Void doInBackground() throws Exception {
            Request request = elevator.pollRequest();
            if (request != null) {
                elevator.moveTo(request.targetFloor); // 执行电梯移动
                openDoorAnimation(); // 到达后开门动画
            }
            return null;
        }

        @Override
        protected void done() {
            // 电梯到达目标楼层后，更新楼层和方向标签
            updateElevatorStatus(String.valueOf(elevator.getCurrentFloor())); // 显示目标楼层
            updateDirection("等待"); // 方向标签显示为 "等待"
            updateLog("电梯到达目标楼层，进入等待状态");
            startWaitTimer(); // 电梯到达目标楼层后，重置并启动等待计时器
            updatePeopleCountLabel(); // 更新电梯人数显示
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new ElevatorGUI());
    }
}
